﻿using ServerBase.Config;
using SvGame.Objects;
using Zpb;

namespace SvGame.Logic;

public static partial class GameLogic
{
    // 创建道具
    public static bool NewItem(ConfigItemExt conf, long count, out Item obj)
    {
        obj = new()
        {
            Uid = IdMgr.CreateObjectId(),
            ConfigId = conf.Id,
            Cfg = conf,
            Count = count,
        };
        return true;
    }
    // 道具信息
    public static ItemInfo GetInfo(this Item obj)
    {
        var info = new ItemInfo();
        info.Uid = obj.Uid;
        info.ConfigId = obj.ConfigId;
        info.Count = obj.Count;
        info.Name = obj._Name;
        info.Desc = obj._Desc;
        return info;
    }
    public static RoleInfoItems InfoItems(this Player player)
    {
        var info = new RoleInfoItems();
        foreach (var item in player.DictItem.Values)
        {
            var node = item.GetInfo();
            info.Items[node.Uid] = node;
        }
        return info;
    }
    /// <summary>
    /// 玩家添加道具
    /// </summary>
    /// <param name="player"></param>
    /// <param name="configId"></param>
    /// <param name="count"></param>
    /// <returns></returns>
    public static bool AddItem(this Player player, int configId, long count)
    {
        if (!ConfItemExt.TryGetValue(configId, out var conf))
        {
            loger.Warn($"Player AddItem 道具配置错误 ConfigId{configId}");
            return false;
        }
        if (count <= 0)
        {
            loger.Warn($"Player AddItem 数目错误 configId{configId} Count{count}");
            return false;
        }
        // 是否可以叠加
        if (conf.SettBase.Stackable)
        {
            var obj = (from it in player.DictItem.Values
                       where (it.ConfigId == configId)
                       select it).FirstOrDefault();
            if (obj is not null)
            {
                obj.Count += count;
            }
            else
            {
                if (NewItem(conf, count, out obj))
                {
                    player.AddItem(obj);
                }
            }
        }
        else
        {
            for (int i = 0; i < count; i++)
            {
                if (NewItem(conf, 1, out var obj))
                {
                    player.AddItem(obj);
                }
            }
        }
        return true;
    }
    public static void AddItem(this Player player, Item obj)
    {
        obj.Env = player;
        player.DictItem[obj.Uid] = obj;
    }
    public static void NtfPlayerItems(this Player player)
    {
        var nrf = new G2CNtfItems();
        nrf.InfoItems = player.InfoItems();
        player.Send(nrf);
    }
    // 玩家从房间拾取道具
    public static void ItemGetFromRoom(this Player player, Item obj)
    {
        player.Room.DictItem.Remove(obj.Uid);
        player.AddItem(obj.ConfigId, obj.Count);
    }
    // 玩家丢下道具到房间
    public static void ItemDropToRoom(this Player player, Item obj, long count)
    {
        player.Room.DictItem[obj.Uid] = obj;
        obj.Count -= count;
        if (obj.Count <= 0)
        {
            player.DictItem.Remove(obj.Uid);
        }
    }
    // 道具使用
    public static string ItemUse(this Player player, Item obj)
    {
        var conf = obj.Cfg;
        if (conf.SettBase.ActType == 0)
        {
            return "这个道具不能使用";
        }
        var flag = 0;
        // todo ItemUse 增加效果
        foreach (var effect in conf.SettBase.UseEffect)
        {
            if (effect.Count > 0)
            {
                if (effect[0] == 0)
                {
                    continue;
                }
                int effectValue = 0;
                if (effect.Count >= 2)
                {
                    effectValue = effect[1];
                }
                var effectType = (EPropType)effect[0];
                switch (effectType)
                {
                    case EPropType.Kee:
                        break;
                    case EPropType.Sen:
                        break;
                    case EPropType.Force:
                        break;
                    case EPropType.Mana:
                        break;
                    case EPropType.Food:
                        if (player.StatusCur.Food >= player.StatusMax.Food)
                        {
                            return "你已经吃太饱了，再也塞不下任何东西了。";
                        }
                        player.StatusCur.Food += effectValue;
                        flag++;
                        break;
                    case EPropType.Water:
                        if (player.StatusCur.Water >= player.StatusMax.Water)
                        {
                            return "你已经喝太多了，再也灌不下一滴水了。";
                        }
                        player.StatusCur.Water += effectValue;
                        flag++;
                        break;
                    case EPropType.EffKee:
                        break;
                    case EPropType.EffSen:
                        break;
                    case EPropType.MaxKee:
                        break;
                    case EPropType.MaxSen:
                        break;
                    case EPropType.MaxForce:
                        break;
                    case EPropType.MaxMana:
                        break;
                    case EPropType.MaxFood:
                        break;
                    case EPropType.MaxWater:
                        break;
                    default:
                        break;
                }
            }
        }
        string useDesc = $"$N使用了一$u$n。";

        // 使用次数
        obj.Tag0++;

        // 判断用完
        if (obj.Tag0 >= conf.SettBase.UseCount)
        {
            if (ConfItemUseDesc.TryGetValue(conf.SettBase.UseDesc, out var confDesc))
            {
                useDesc = confDesc.EmptyDesc;
            }
            EItemType itemType = (EItemType)conf.SettBase.ItemType;
            if (itemType != EItemType.饮具)
            {
                obj.Count -= 1;
                if (obj.Count <= 0)
                {
                    player.DictItem.Remove(obj.Uid);
                }
            }
        }
        else
        {
            if (ConfItemUseDesc.TryGetValue(conf.SettBase.UseDesc, out var confDesc))
            {
                useDesc = confDesc.UseDesc;
            }
        }

        useDesc = useDesc.Replace("$u", conf.SettBase.Unit);
        useDesc = useDesc.Replace("$n", obj.Name);
        MessageVision(useDesc, player);

        if (flag > 0)
        {
            player.Hp();
        }
        
        return string.Empty;
    }
    // 道具动作
    public static string ItemAct(this Player player, Item obj, EActType act)
    {
        switch (act)
        {
            case EActType.装水:
                if (!player.Room.CfgExt.Resources.Contains(EResourceType.饮水))
                {
                    return "这里没有地方可以装水。";
                }
                MessageVision($"$N将{obj.Name}装满清水。", player);
                player.BusyStart(2000);
                break;
            default:
                break;
        }

        return string.Empty;
    }
}
